package cn.buddha.jesw.flux.controller;

import cn.buddha.jesw.flux.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName HelloWebFluxController
 * @Author 友野浩二
 * @Date 2019/11/21 12:48
 * @Description webflux测试控制类
 * @Version 1.0
 *
 * <pre>
 *     1- Flux 和 Mono 是 Reactor 中的两个基本概念。
 *     2- Flux 表示的是包含 0 到 N 个元素的异步序列。
 *          在该序列中可以包含三种不同类型的消息通知：正常的包含元素的消息、序列结束的消息和序列出错的消息。
 *          当消息通知产生时，订阅者中对应的方法 onNext(), onComplete()和 onError()会被调用。
 *     3- Mono 表示的是包含 0 或者 1 个元素的异步序列。 该序列中同样可以包含与 Flux 相同的三种类型的消息通知。
 *     5- Flux 和 Mono 之间可以进行转换。
 *          对一个 Flux 序列进行计数操作，得到的结果是一个 Mono对象。把两个 Mono 序列合并在一起，得到的是一个 Flux 对象。
 * </pre>
 */
@RestController
@Slf4j
public class HelloWebFluxController {

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String hello() {
        return "Hello, WebFlux!";
    }

    /**
     * @return reactor.core.publisher.Mono<cn.buddha.jesw.flux.model.User>
     * <pre>
     *     Mono：返回 0 或 1 个元素，即单个对象。
     *     在 WebFlux 中，Mono 是非阻塞的写法，只有使用Mono包装user对象，才能发挥 WebFlux 【非阻塞 + 异步】 的特性。
     * </pre>
     * @Author 友野浩二
     * @Description // 返回单个user对象数据
     * @Date 2019/11/21 12:59
     * @Param []
     **/
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public Mono<User> getUser() {
        return Mono.just(User.builder().name("石浩").sex("B").age(25).build());
    }

    private static List<User> userList = new ArrayList<>();

    @PostConstruct
    public void init() {
        userList.add(User.builder().name("浩浩").sex("B").age(25).build());
        userList.add(User.builder().name("彤彤").sex("G").age(25).build());
    }

    @RequestMapping(value = "/allUser", method = RequestMethod.POST)
    public Flux<User> getAllUser() {
        return Flux.fromStream(userList.stream());
    }

}
